package com.si.dao;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.ScrollableResults;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.si.util.Paging;
import com.si.util.QueryWhere;

public class EntityDaoImpl extends HibernateDaoSupport implements EntityDao {

	public List createCriteria(final Class cs) {
		return (List) getHibernateTemplate().execute(
			new HibernateCallback<Object>() {
				public Object doInHibernate(org.hibernate.Session session)
						throws org.hibernate.HibernateException {
					Criteria criteria = session.createCriteria(cs);
					if (session != null && session.isConnected()) {
						session.close();
					}
					return criteria.list();
				}
			});
	}
	@SuppressWarnings("unchecked")
	public List createCriteria(final Class cs, final Map<String, Object> map,
			final Map<String, Object> orderMap) {
		return (List) getHibernateTemplate().execute(
				new HibernateCallback<Object>() {
					public Object doInHibernate(org.hibernate.Session session)
							throws org.hibernate.HibernateException {
						Criteria criteria = session.createCriteria(cs);
						if (map != null) {
							Set<String> key = map.keySet();
							for (Iterator it = key.iterator(); it.hasNext();) {
								String s = (String) it.next();
								if (s.indexOf(">=") != -1) {
									criteria.add(Restrictions.gt(s.replace(">=", ""), map.get(s)));
								} else if (s.indexOf("<=") != -1) {
									criteria.add(Restrictions.lt(s.replace("<=",""), map.get(s)));
								} else if (s.indexOf("%") != -1) {
									criteria.add(Restrictions.like(s.replace("%", ""), "%" + map.get(s) + "%"));
								}else if (s.indexOf("!=") != -1) {
									criteria.add(Restrictions.ne(s.replace("!=",""), map.get(s)));
								}else if(s.indexOf("||") != -1){
									String w1=s.split("\\|\\|")[0];
									String w2=s.split("\\|\\|")[1];
									criteria.add(
											Restrictions.or(
												Restrictions.like(w1,"%" +map.get(s)+ "%"),
												Restrictions.like(w2,"%" +map.get(s)+ "%"))
											);
								}else {
									criteria.add(Restrictions.eq(s, map.get(s)));
								}
							}
						}
						if (orderMap != null) {
							Set<String> key = orderMap.keySet();
							for (Iterator it = key.iterator(); it.hasNext();) {
								String s = (String) it.next();
								if (orderMap.get(s).equals("desc")) {
									criteria.addOrder(Order.desc(s));
								} else {
									criteria.addOrder(Order.asc(s));
								}
							}
						}
						if (session != null && session.isConnected()) {
							session.close();
						}
						return criteria.list();
					}
				});
	}

	@SuppressWarnings("unchecked")
	public Paging createQueryPaging(final Class cs,
			final Map<String, Object> map, final Map<String, Object> orderMap,
			final Integer curPage, final Integer pageSize) {
		return (Paging) getHibernateTemplate().execute(
				new HibernateCallback<Object>() {
					public Object doInHibernate(org.hibernate.Session session)
							throws org.hibernate.HibernateException {
						Paging paging = new Paging();
						Criteria criteria = session.createCriteria(cs);
						if (map != null) {
							Set<String> key = map.keySet();
							for (Iterator it = key.iterator(); it.hasNext();) {
								String s = (String) it.next();
								if (s.indexOf(">=") != -1) {
									criteria.add(Restrictions.gt(s.replace(">=", ""), map.get(s)));
								} else if (s.indexOf("<=") != -1) {
									criteria.add(Restrictions.lt(s.replace("<=",""), map.get(s)));
								} else if (s.indexOf("%") != -1) {
									criteria.add(Restrictions.like(s.replace("%", ""), "%" + map.get(s) + "%"));
								}else if (s.indexOf("!=") != -1) {
									criteria.add(Restrictions.ne(s.replace("!=",""), map.get(s)));
								}else if(s.indexOf("||") != -1){
									String w1=s.split("\\|\\|")[0];
									String w2=s.split("\\|\\|")[1];
									criteria.add(
											Restrictions.or(
												Restrictions.like(w1,"%" +map.get(s)+ "%"),
												Restrictions.like(w2,"%" +map.get(s)+ "%"))
											);
								}else {
									criteria.add(Restrictions.eq(s, map.get(s)));
								}
							}
						}
						if (orderMap != null) {
							Set<String> key = orderMap.keySet();
							for (Iterator it = key.iterator(); it.hasNext();) {
								String s = (String) it.next();
								if (orderMap.get(s).equals("desc")) {
									criteria.addOrder(Order.desc(s));
								} else {
									criteria.addOrder(Order.asc(s));
								}
							}
						}
						
						//得到滚动结果集
				        ScrollableResults scroll = criteria.scroll();
				        scroll.last();//滚动到最后一行
				        int totalRows = scroll.getRowNumber() + 1;//总条数
						paging.setTotalPage(totalRows);
						paging.setCurPage(curPage);
						paging.setPageSize(pageSize);
						
						criteria.setFirstResult(curPage * pageSize);
						criteria.setMaxResults(pageSize);
						paging.setData(criteria.list());
						

						if (session != null && session.isConnected()) {
							session.close();
						}
						return paging;
					}
				});
	}

	public Object update(final Object model) {
		return getHibernateTemplate().execute(new HibernateCallback<Object>() {
			public Object doInHibernate(org.hibernate.Session session)
					throws org.hibernate.HibernateException {
				session.saveOrUpdate(model);
				if (session != null && session.isConnected()) {
					session.close();
				}
				return null;
			}
		});
	}

	public Object save(final Object model) {
		return getHibernateTemplate().execute(new HibernateCallback<Object>() {
			public Object doInHibernate(org.hibernate.Session session)
					throws org.hibernate.HibernateException {
				session.save(model);
				if (session != null && session.isConnected()) {
					session.close();
				}
				return null;
			}
		});
	}
	 public void delete(final Object model) {   
	        getHibernateTemplate().execute(new HibernateCallback<Object>() {   
	            public Object doInHibernate(org.hibernate.Session session)   
	                    throws org.hibernate.HibernateException {   
	                session.delete(model);  
	                if(session!=null && session.isConnected()){
	                	session.close();
	                }
	                return null;   
	            }   
	        });   
	    }
	@SuppressWarnings("unchecked")
	public Object getObjectById(final Class cs, final Integer id) {
		return (Object) getHibernateTemplate().get(cs, id);
	}

	@SuppressWarnings("unchecked")
	public Object getObjectById(final Class cs, final String id) {
		return (Object) getHibernateTemplate().get(cs, id);
	}
	public Integer createSqlExecuteUpdate(final String queryString) {
		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback<Object>() {
					public Integer doInHibernate(
							org.hibernate.Session session)
							throws org.hibernate.HibernateException {
						Integer rows = session.createSQLQuery(queryString).executeUpdate();
						if (session != null && session.isConnected()) {
							session.close();
						}
						return rows;
					}
				});
	}
	
	@SuppressWarnings("unchecked")
	public String createSql(final String queryString) {
		return (String) getHibernateTemplate().execute(
				new HibernateCallback<Object>() {
					public String doInHibernate(
							org.hibernate.Session session)
							throws org.hibernate.HibernateException {
						SQLQuery query = session.createSQLQuery(queryString);
						Object   rows = query.list();
						if (session != null && session.isConnected()) {
							session.close();
						}
						return rows.toString();
					}
				});
	}

	/**
	 * sqlQuery
	 */
	@SuppressWarnings("unchecked")
	public List<Object[]> createSqlQuery(final String queryString) {
		return (List<Object[]>) getHibernateTemplate().execute(
				new HibernateCallback<Object>() {
					public List<Object[]> doInHibernate(
							org.hibernate.Session session)
							throws org.hibernate.HibernateException {
						SQLQuery query = session.createSQLQuery(queryString);
						List<Object[]> rows = query.list();
						if (session != null && session.isConnected()) {
							session.close();
						}
						return rows;
					}
				});
	}
	
	public Object saveOrUpdate(final Object model) {
		return getHibernateTemplate().execute(new HibernateCallback<Object>() {
			public Object doInHibernate(org.hibernate.Session session)
					throws org.hibernate.HibernateException {
				session.saveOrUpdate(model);
				if (session != null && session.isConnected()) {
					session.close();
				}
				return null;
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public Paging createCriteriaPaging(final Class cs ,final Integer curPage, final Integer pageSize) {
		return (Paging) getHibernateTemplate().execute(
				new HibernateCallback<Object>() {
					public Object doInHibernate(org.hibernate.Session session)
							throws org.hibernate.HibernateException {
						Paging paging = new Paging();
						Criteria criteria = session.createCriteria(cs);
						List<Criterion> queryList=QueryWhere.getQueryList();
						List<String> aliasList=QueryWhere.getAliasList();
						List<Order> orderList=QueryWhere.getOrderList();

						for (int i = 0; i <aliasList.size(); i++) {
							criteria.createAlias(aliasList.get(i),aliasList.get(i));
						}

						for (int i = 0; i <queryList.size(); i++) {
							criteria.add((Criterion)queryList.get(i));
						}

						for (int i = 0; i <orderList.size(); i++) {
							criteria.addOrder(orderList.get(i));
						}
						//得到滚动结果集
						ScrollableResults scroll = criteria.scroll();
						scroll.last();//滚动到最后一行
						int totalRows = scroll.getRowNumber() + 1;//总条数
						paging.setTotalPage(totalRows);
						paging.setCurPage(curPage);
						paging.setPageSize(pageSize);

						criteria.setFirstResult(curPage * pageSize);
						criteria.setMaxResults(pageSize);
						paging.setData(criteria.list());


						if (session != null && session.isConnected()) {
							session.close();
						}

						QueryWhere.remove();
						return paging;
					}
				});
	}
}
